﻿#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<string>
#include<vector>
using namespace std;

//template <class _Ty>
//remove_reference_t<_Ty>&& move(_Ty&& _Arg)
//{
//	// forward _Arg as movable
//	return static_cast<remove_reference_t<_Ty>&&>(_Arg);
//}

//int main()
//{
//	// 左值：可以取地址
//	// 以下的p、b、c、*p、s、s[0]就是常⻅的左值
//	int* p = new int(0);
//	int b = 1;
//	const int c = b;
//	*p = 10;
//	string s("111111");
//	s[0] = 'x';
//	double x = 1.1, y = 2.2;
//	
//	int& r1 = b;
//	int*& r2 = p;
//	int& r3 = *p;
//	string& r4 = s;
//	char& r5 = s[0];
//
//	// 右值引⽤给右值取别名
//	int&& rr1 = 10;
//	double&& rr2 = x + y;
//	double&& rr3 = fmin(x, y);
//	string&& rr4 = string("11111");
//	
//	const int& rx1 = 10;
//	const double& rx2 = x + y;
//	const double& rx3 = fmin(x, y);
//	const string& rx4 = string("11111");
//	
//	int&& rrx1 = move(b);
//	int*&& rrx2 = move(p);
//	int&& rrx3 = move(*p);
//	string&& rrx4 = move(s);
//	string&& rrx5 = (string&&)s;
//	
//	cout << &b << endl;
//	cout << &r1 << endl;
//	cout << &rr1 << endl;
//	
//	int& r6 = r1;
//	// int&& rrx6 = rr1;
//	int&& rrx6 = move(rr1);
//	return 0;
//}
//class Solution {
//public:
//	// 传值返回需要拷⻉
//	string addStrings(string num1, string num2) {
//		string str;
//		int end1 = num1.size() - 1, end2 = num2.size() - 1;
//		// 进位
//		int next = 0;
//		while (end1 >= 0 || end2 >= 0)
//		{
//			int val1 = end1 >= 0 ? num1[end1--] - '0' : 0;
//			int val2 = end2 >= 0 ? num2[end2--] - '0' : 0;
//			int ret = val1 + val2 + next;
//			next = ret / 10;
//			ret = ret % 10;
//			str += ('0' + ret);
//		}
//		if (next == 1)
//			str += '1';
//		reverse(str.begin(), str.end());
//		return str;
//	}
//
//	// 这⾥的传值返回拷贝代价就太⼤了
//	vector<vector<int>> generate(int numRows) {
//		vector<vector<int>> vv(numRows);
//		for (int i = 0; i < numRows; ++i)
//		{
//			vv[i].resize(i + 1, 1);
//		}
//		for (int i = 2; i < numRows; ++i)
//		{
//			for (int j = 1; j < i; ++j)
//			{
//				vv[i][j] = vv[i - 1][j] + vv[i - 1][j - 1];
//			}
//		}
//		return vv;
//	}
//};
//
//int main() {
//	Solution ss;
//	string ret1 = ss.addStrings("1111111","222222");
//	vector<vector<int>> ret2 = ss.generate (19);
//
//	return 0;
//}

//#define _CRT_SECURE_NO_WARNINGS 1
//#include<iostream>
//#include<assert.h>
//#include<string.h>
//#include<algorithm>
//using namespace std;
//namespace wjx {
//
//		class string
//		{
//		public:
//			typedef char* iterator;
//			typedef const char* const_iterator;
//			iterator begin()
//			{
//				return _str;
//			}
//			iterator end()
//			{
//				return _str + _size;
//			}
//			const_iterator begin() const
//			{
//				return _str;
//			}
//			const_iterator end() const
//			{
//				return _str + _size;
//			}
//			string(const char* str = "")
//				:_size(strlen(str))
//				, _capacity(_size)
//			{
//				cout << "string(char* str)-构造" << endl;
//				_str = new char[_capacity + 1];
//				strcpy(_str, str);
//			}
//			void swap(string& s)
//			{
//				::swap(_str, s._str);
//				::swap(_size, s._size);
//				::swap(_capacity, s._capacity);
//			}
//			string(const string& s)
//				:_str(nullptr)
//			{
//				cout << "string(const string& s) -- 拷贝构造" << endl;
//				reserve(s._capacity);
//				for (auto ch : s)
//				{
//					push_back(ch);
//				}
//			}
//			// 移动构造
//			string(string&& s)
//			{
//				cout << "string(string&& s) -- 移动构造" << endl;
//				swap(s);
//			}
//			string& operator=(const string& s)
//			{
//				cout << "string& operator=(const string& s) -- 拷贝赋值" <<
//					endl;
//				if (this != &s)
//				{
//					_str[0] = '\0';
//					_size = 0;
//					reserve(s._capacity);
//					for (auto ch : s)
//					{
//						push_back(ch);
//					}
//				}
//				return *this;
//			}
//			// 移动赋值
//			string& operator=(string&& s)
//			{
//				cout << "string& operator=(string&& s) -- 移动赋值" << endl;
//				swap(s);
//				return *this;
//			}
//			~string()
//			{
//				cout << "~string() -- 析构" << endl;
//				delete[] _str;
//				_str = nullptr;
//			}
//			char& operator[](size_t pos)
//			{
//				assert(pos < _size);
//				return _str[pos];
//			}
//			void reserve(size_t n)
//			{
//				if (n > _capacity)
//				{
//					char* tmp = new char[n + 1];
//					if (_str)
//					{
//						strcpy(tmp, _str);
//						delete[] _str;
//					}
//					_str = tmp;
//					_capacity = n;
//				}
//			}
//			void push_back(char ch)
//			{
//				if (_size >= _capacity)
//				{
//					size_t newcapacity = _capacity == 0 ? 4 : _capacity *
//						2;
//					reserve(newcapacity);
//				}
//				_str[_size] = ch;
//				++_size;
//				_str[_size] = '\0';
//			}
//			string& operator+=(char ch)
//			{
//				push_back(ch);
//				return *this;
//			}
//			const char* c_str() const
//			{
//				return _str;
//			}
//			size_t size() const
//			{
//				return _size;
//			}
//private:
//	char* _str = nullptr;
//	size_t _size = 0;
//	size_t _capacity = 0;
//};
//}
//int main()
//{
//	wjx::string s = "111111111";
//
//	wjx::string s1 = s;//拷贝构造
//
//	wjx::string s2("xxxxxxxxx");
//
//	// 构造+移动构造，优化后直接构造
//	wjx::string s3 = wjx::string("yyyyy");
//	// 移动构造
//	wjx::string s4 = move(s1);
//	cout << "******************************" << endl;
//	return 0;
//	 
//}

// 由于引⽤折叠限定，f1实例化以后总是⼀个左值引⽤
//template<class T>
//void f1(T& x)
//{}
//
//// 由于引⽤折叠限定，f2实例化后可以是左值引⽤，也可以是右值引⽤
//template<class T>
//void f2(T&& x)
//{}
//
//int main() {
//
//	typedef int& lref;
//	typedef int&& rref;
//	int n = 0;
//
//	lref& x1 = n;//折叠为int&
//	lref&& x2 = n;//折叠为int&
//	rref& x3 = n;//折叠为int&
//	rref&& x4 = 0;
//
//	// 没有折叠->实例化为void f1(int& x)
//	f1<int>(n);
//	//f1<int>(0); // 报错
//	// 折叠->实例化为void f1(int& x)
//	f1<int&>(n);
//	//f1<int&>(0); // 报错
//	// 折叠->实例化为void f1(int& x)
//	f1<int&&>(n);
//	//f1<int&&>(0); // 报错
//
//	// 折叠->实例化为void f1(const int& x)
//	f1<const int&>(n);
//	f1<const int&>(0);
//	return 0;
//}


//template<class T>
//void Function(T&& t)
//{
//	int a = 0;
//	T x = a;
//	//x++;
//	cout << &a << endl;
//	cout << &x << endl << endl;
//}
//int main()
//{
//	// 10是右值，推导出T为int，模板实例化为void Function(int&& t)
//	Function(10);
//	// 右值
//
//	int a;
//	// a是左值，推导出T为int&，引⽤折叠，模板实例化为void Function(int& t)
//	Function(a);
//	// 左值
//	
//	// std::move(a)是右值，推导出T为int，模板实例化为void Function(int&& t)
//	Function(std::move(a));
//	// 右值
//
//	const int b = 8;
//	// b是左值，推导出T为const int&，引⽤折叠，模板实例化为void Function(const int&	t)
//	// 所以Function内部会编译报错，x不能++
//		Function(b);
//	// const 左值
//	
//	// std::move(b)右值，推导出T为const int，模板实例化为void Function(const int&&	t)
//	// 所以Function内部会编译报错，x不能++
//		Function(std::move(b));
//	// const 右值
//
//		int* num = new int[20] {1, 1, 1};
//
//	return 0;
//}



void showlist() {
	cout << endl;
}

template<class T ,class ...Arges>
void showlist(T& x, Arges&& ... arges) {
	cout << x << ' ';
	showlist(arges...);
}

template<class ...Arges>
void Print(Arges&&... arges) {

	showlist(arges...);
}

//int main() {
//
//	//double x = 2.2;
//	//Print();
//	//// 包⾥有0个参数
//	//Print(1);
//	//// 包⾥有1个参数
//	//Print(1, string("xxxxx"));
//	//// 包⾥有2个参数
//	//Print(1.1, string("xxxxx"), x);
//	// 包⾥有3个参数
//
//	//Print();
//	//Print(1);
//	//Print(1, string("xxxxx"));
//	//Print(1, string("xxxxx"), 2.2);
//
//	auto f = [](int a, int b) ->int {
//		return a + b;
//		};
//	cout << f(1, 2) << endl;
//
//	//shared_ptr<T>& operator=(const shared_ptr<T>& sp)
//	//{
//	//	*_pcont--;
//
//	//	if(*_pcount == 0)
//	//		//掉析构
//	//	_ptr = sp._ptr;
//	//	_pcount = sp._pcount;
//	//	*_pconnt++;
//	//	return *this;
//	//}
//	return 0;
//}

double func1(int a , int b) {
	try
	{
		// 当b == 0时抛出异常
		if (b == 0)
		{
			string s("Divide by zero condition!");
			throw s;
		}
		else
		{
			return ((double)a / (double)b);
		}
	}
	catch (int errid)
	{
		cout << errid << endl;
	}
	return 0;

}
void Func()
{
	int len, time;
	cin >> len >> time;
	try
	{
		cout << func1(len, time) << endl;
	}
	catch ( string errmsg)
	{
		cout << errmsg << endl;
	}
	cout << __FUNCTION__ << ":" << __LINE__ << "行执行" << endl;
}
//int main()
//{
//	while (1)
//	{
//		try
//		{
//			Func();
//		}
//		catch (const string& errmsg)
//		{
//			cout << errmsg << endl;
//		}
//	}
//	return 0;
//}

// 下⾯程序模拟展⽰了聊天时发送消息，发送失败补货异常，但是可能在
// 电梯地下室等场景⼿机信号不好，则需要多次尝试，如果多次尝试都发
// 送不出去，则就需要捕获异常再重新抛出，其次如果不是⽹络差导致的
// 错误，捕获后也要重新抛出。

#include<thread>
#include<exception>

class Exception
{
public:
	Exception(const string& errmsg, int id)
		:_errmsg(errmsg)
		, _id(id)
	{}
	virtual string what() const
	{
		return _errmsg;
	}
	int getid() const
	{
		return _id;
	}
protected:
	string _errmsg;
	int _id;
};

class HttpException : public Exception
{
public:
	HttpException(const string& errmsg, int id, const string& type)
		:Exception(errmsg, id)
		, _type(type)
	{}
	virtual string what() const
	{
		string str = "HttpException:";
		str += _type;
		str += ":";
		str += _errmsg;
		return str;
	}
private:
	const string _type;
};

void _SeedMsg(const string& s)
{
	if (rand() % 2 == 0)
	{
		throw HttpException("网络不稳定，发送失败", 102, "put");
	}
	else if (rand() % 7 == 0)
	{
		throw HttpException("你已经不是对象的好友，发送失败", 103, "put");
	}
	else
	{
		cout << "发送成功" << endl;
	}
}
void SendMsg(const string& s)
{
	// 发送消息失败，则再重试3次
	for (size_t i = 0; i < 4; i++)
	{
		try
		{
			_SeedMsg(s);
			break;
		}
		catch (const Exception& e)
		{
			// 捕获异常，if中是102号错误，⽹络不稳定，则重新发送
			// 捕获异常，else中不是102号错误，则将异常重新抛出
			if (e.getid() == 102)
			{
				// 重试三次以后否失败了，则说明⽹络太差了，重新抛出异常
				if (i == 3)
					throw;
				cout << "开始第" << i + 1 << "重试" << endl;
			}
			else
			{
				throw;
			}
		}
	}
}
//int main()
//{
//	srand(time(0));
//	string str;
//	while (cin >> str)
//	{
//		try
//		{
//			SendMsg(str);
//		}
//		catch (const Exception& e)
//		{
//			cout << e.what() << endl << endl;
//		}
//		catch (...)
//		{
//			cout << "Unkown Exception" << endl;
//		}
//	}
//	return 0;
//}

//#include<memory>
//int main() {
//
//std::auto_ptr<string> ptr1(new string("hello word!"));
//std::auto_ptr<string> ptr2(ptr1);
//
//	return 0;
//}

//#include<memory>
//int main() {
//
//	std::unique_ptr<string> ptr1(new string("hello word!"));
//	std::unique_ptr<string> ptr2 = move(ptr1);
//
//	return 0;
//}

#include<memory>

namespace wjx {
	template<class T>
	class shared_ptr {
	public:
		shared_ptr(T* ptr = nullptr)
			: _ptr(ptr)
			, _pcount(new int(1))
		{}
		shared_ptr(const shared_ptr<T>& st) {
			_ptr = st._ptr;
			_pcount = st._pcount;
			(*_pcount)++;
		}
		~shared_ptr() {
			if (--(*_pcount) == 0)
			{
				delete _pcount;
				delete _ptr;
				_pcount = nullptr;
				_ptr = nullptr;
			}
		}

		shared_ptr<T>& operator=(const shared_ptr<T>& ptr) {
			if (*this != ptr) {
				if (--(*_pcount) == 0) {
					delete _pcount;
					delete _ptr;
					_pcount = nullptr;
					_ptr = nullptr;
				}
				_ptr = ptr._ptr;
				_pcount = ptr._pcount;
				(*_pcount)++;
			}
			return *this;
		}
		T& operator*() {
			return *_ptr;
		}
		T* operator->() {
			return _ptr;
		}
	private:
		T* _ptr;
		int* _pcount;
	};
};
int main() {

	wjx::shared_ptr<string> ptr1(new string("hello word!"));
	wjx::shared_ptr<string> ptr2 = ptr1;
	*ptr1 += "wjx";
	cout << *ptr1 << endl;
	cout << *ptr2 << endl;

	return 0;
}